﻿using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using VOL.Core.Extensions;

namespace VOL.Core.Files
{
    /// <summary>
    /// 压缩文件
    /// </summary>
    public class Commpress
    {
        public static string GetMd5(string text)
        {
            var md5Bytes = MD5.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text));

            return GetMd5Text(md5Bytes);
        }

        public static string GetMd5(byte[] buffer)
        {
            var md5Bytes = MD5.Create().ComputeHash(buffer);

            return GetMd5Text(md5Bytes);
        }

        private static string GetMd5Text(byte[] md5Bytes)
        {
            return BitConverter.ToString(md5Bytes).Replace("-", "").ToLower();
        }

        //文件名称为MD5编码
        public static IEnumerable<dynamic> Fetch(List<string> files)
        {
            return files.Select(o => new
            {
                md5 = GetMd5(o),
                contenttype = Path.GetExtension(o),
                name = Path.GetFileNameWithoutExtension(o),
                extension = Path.GetExtension(path: o).Substring(1),
                rdate = "",
                file = o,
            });
        }
        
        /// <summary>
        /// 压缩文件为zip格式，返回压缩文件路径和名称
        /// </summary>
        /// <param name="documents"></param>
        /// <returns></returns>
        public static string Compress(IEnumerable<dynamic> documents)
        {
            var temp = (@"Download/ZipTemp").MapPath().ReplacePath();
            if (!Directory.Exists(temp))
            {
                Directory.CreateDirectory(temp);
            }
            var md5s = string.Join(",", documents.Select(o => o.md5));
            var md5 = GetMd5(md5s);
            var zipName = string.Format("{0}\\{1}{2}", temp, md5, ".zip");
            if (File.Exists(zipName))
            {
                return zipName;
            }
            using (ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(zipName)))
            {
                zipOutputStream.SetLevel(9);
                var abyBuffer = new byte[4096];
                foreach(dynamic document in documents)
                {
                    try
                    {
                        string filename = document.file;
                        string name = document.name;
                        if (string.IsNullOrEmpty(filename))
                        {
                            continue;
                        }
                        string extension = document.extension;
                        using (FileStream filestream = File.OpenRead(filename))
                        {
                            var zipEntry = new ZipEntry(name + "." + extension);
                            zipEntry.DateTime = DateTime.Now;
                            zipEntry.Size = filestream.Length;
                            zipOutputStream.PutNextEntry(zipEntry);
                            StreamUtils.Copy(filestream, zipOutputStream, abyBuffer);
                        }
                    }catch(Exception)
                    {
                        continue;
                    }
                }
            }
            return zipName;
        }
    }
}
